/*
命令模式（Command Pattern）是一种行为型设计模式，它将请求封装成一个对象，
从而使得可以用不同的请求对客户进行参数化，同时支持对请求排队或记录请求日志，以及支持可撤销的操作。

命令模式的核心思想是将请求与具体的执行操作解耦，通过将请求封装成一个对象，
使得可以对请求进行参数化和操作，从而实现请求的发送者和请求的接收者之间的解耦。

命令模式包含以下几个关键角色：

● Command（命令）：定义了执行操作的接口。
● ConcreteCommand（具体命令）：实现了Command接口，负责执行具体的操作。
● Receiver（接收者）：负责执行具体的操作。
● Invoker（调用者）：负责调用命令对象执行请求。
● Client（客户端）：创建命令对象，并设置其接收者。

下面是一个使用命令模式的C语言例程，用于实现一个简单的遥控器控制电视的功能：
*/

#include <stdio.h>

// 命令接口
typedef struct
{
    void (*execute)(void);
} Command;

// 具体命令
typedef struct
{
    Command base;
    void (*execute)(void);
} ConcreteCommand;

void turnOnTV(void)
{
    printf("Turn on the TV.\n");
}

void turnOffTV(void)
{
    printf("Turn off the TV.\n");
}

Command *createCommand(void (*execute)(void))
{
    ConcreteCommand *command = (ConcreteCommand *)malloc(sizeof(ConcreteCommand));
    command->base.execute = execute;
    command->execute = execute;
    return (Command *)command;
}

// 调用者
typedef struct
{
    Command *command;
    void (*setCommand)(struct Invoker *invoker, Command *command);
    void (*executeCommand)(struct Invoker *invoker);
} Invoker;

void setCommand(Invoker *invoker, Command *command)
{
    invoker->command = command;
}

void executeCommand(Invoker *invoker)
{
    invoker->command->execute();
}

// 客户端代码
int main()
{
    Invoker invoker;

    Command *turnOnCommand = createCommand(turnOnTV);
    Command *turnOffCommand = createCommand(turnOffTV);

    setCommand(&invoker, turnOnCommand);
    executeCommand(&invoker);

    setCommand(&invoker, turnOffCommand);
    executeCommand(&invoker);

    return 0;
}

/*
在上面的例程中，首先定义了命令接口Command，其中包含了一个execute方法。
然后，定义了具体命令ConcreteCommand，它实现了Command接口，并包含了一个指向具体操作的函数指针。
在createCommand函数中，创建了一个新的具体命令对象，并设置其执行操作。
接下来，定义了调用者Invoker，它包含了一个命令对象，并提供了设置命令和执行命令的方法。
在main函数中，创建了一个调用者对象，并创建了两个具体命令对象，然后将具体命令对象设置到调用者中，并执行命令。

通过使用命令模式，我们可以将请求封装成一个对象，并将请求的发送者和请求的接收者解耦。
命令模式适用于需要将请求参数化、排队或记录日志、支持可撤销的操作的场景。
*/